package com.kele.basic;

import lombok.Data;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author chunhui.li
 * @date 2022/1/22 10:33
 * @Description 使用tryLock避免死锁,设置超时时间来避免死锁,不设置超时时间就是立刻退出
 * @ClassName DeadTryLock
 */
@Data
public class DeadTryLock implements Runnable {

    private static ReentrantLock lock = new ReentrantLock();
    private static ThreadFactory namedFactory = nameThreadFactory();
    @Override
    public void run() {
        try {
            if (lock.tryLock(3,TimeUnit.SECONDS)){
                System.out.println(Thread.currentThread().getName()+"-->");
                Thread.sleep(2000);
            } else {
                System.out.println(Thread.currentThread().getName()+" time out ");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println(Thread.currentThread().getName()+"unLock");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        DeadTryLock deadTryLock = new DeadTryLock();

        /**
         * 使用线程池创建线程
         */

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                3,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory());

        /**
         * 使用线程池创建两个线程
         */
        try {
            for (int i = 0; i < 2; i++) {
                threadPoolExecutor.execute(deadTryLock);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPoolExecutor.shutdown();
        }
//        Thread thread1 = new Thread(deadTryLock,"t1");
//        Thread thread2 = new Thread(deadTryLock,"t2");
//        thread1.start();
////        thread1.join();
//        thread2.start();
    }

    /**
     * 自定义ThreadFactory
     */
    private static ThreadFactory nameThreadFactory(){
        AtomicInteger tag = new AtomicInteger(1);
        ThreadFactory factory = (Runnable r) -> {
            Thread thread = new Thread(r);
            thread.setName("线程-demo-" + tag.getAndIncrement());
            return thread;
        };

        return factory;
    }
}
